/**
 * 
 */
package com.cipe.cmrs.service.impl;

import java.util.List;

import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.cipe.cmrs.model.User;
import com.cipe.cmrs.service.BaseService;
import com.cipe.cmrs.service.UserService;
import com.cipe.cmrs.util.DateUtil;
import com.cipe.cmrs.util.PasswordEncryptionUtil;
import com.cipe.cmrs.util.UserUtil;
import com.cipe.cmrs.util.Util;

/**
 * @author Incepio
 * 
 */

@Service("userService")
@Transactional
public class UserServiceImpl extends BaseService<User> implements UserService, UserDetailsService {
    @Transactional(readOnly = true)
    public User loadUserByUsername(String loginname) throws UsernameNotFoundException {
        User user = getUserByLoginName(loginname);
        return user;
    }

    /**
     * 
     * @param user
     * @return
     */

    public User authenticUser(User user) {
        if (user != null) {
            return getUserByLoginNamePassword(user.getLoginName(), user.getPassword());
        }
        return null;
    }

    /**
     * 
     * @param emailAddress
     * @param password
     * @return
     */
    public User getUserByLoginName(String loginName) {
        User user = null;
        try {

            List<User> uList = dao.getResultList("from User where loginname='" + loginName + "'");
            if (uList != null && uList.size() > 0)
                user = uList.get(0);
        } catch (Exception exp) {
            logger.warn(exp.toString());
        }
        return user;
    }

    public User getUserByLoginNamePassword(String loginName, String password) {
        if (Util.isNullOrEmpty(loginName) || Util.isNullOrEmpty(password)) {
            return null;
        }
        String encryptPassword = PasswordEncryptionUtil.getEncryptedPassword(password);
        Object[] params = { loginName.toLowerCase(), encryptPassword };
        User user = null;
        try {
            user = dao.getSingleNamedQueryResult("getUserByLoginNameAndPassword", params);
        } catch (Exception exp) {
            logger.warn(exp.toString());
        }
        return user;
    }

    public boolean changePassword(User user) {
        User dbUser = getUserByLoginNamePassword(user.getLoginName(), user.getPassword());
        if (dbUser != null) {
            dbUser.setPassword(PasswordEncryptionUtil.getEncryptedPassword(user.getNewPassword()));
            merge(dbUser);
            return true;
        }
        return false;
    }

    public User saveUser(User user, Integer userId) {
        if (user != null) {
        	User loginUser = UserUtil.INSTANCE.getCurrentUser();
            User dbUser = findById(user.getId());
            if (dbUser == null) {
                dbUser = new User();         
                dbUser.setCreatedBy(loginUser);
                dbUser.setCreationDate(DateUtil.getCurrentDate());
            }            
            dbUser.setFirstName(user.getFirstName());
            dbUser.setLastName(user.getLastName());
            dbUser.setMiddleName(user.getMiddleName());
            dbUser.setLoginName(user.getLoginName());
            dbUser.setStartDate(user.getStartDate());
            dbUser.setEndDate(user.getEndDate());
            dbUser.setPassword(PasswordEncryptionUtil.getEncryptedPassword(user.getPassword()));
            dbUser.setEmail(user.getEmail());
            dbUser.setPhone(user.getPhone());
            dbUser.setStatusCode(user.getStatusCode());
            dbUser.setEmployeeId(user.getEmployeeId());
            dbUser.setUpdatedBy(loginUser);
            dbUser.setUpdationDate(DateUtil.getCurrentDate());
            return merge(dbUser);
        }
        
        return null;
    }

    public List<User> findAllByOrderByFullName() {
        String query = "from User u order by firstName,lastName ASC";
        // String query =
        // "from User u where u.id = u.region.regionalDirector order by firstName,lastName ASC";
        return dao.getResultList(query);
    }

    public List<User> getActiveAndDefaultUsersByOrderByFullName() {
        String query = "from User u where statuscode='Active' OR u.id in (select regionalDirector from Region) OR u.id in (select programOfficer from Country) OR u.id in (select programAssistant from Country)";
        return dao.getResultList(query);
    }

    public User getUserById(Integer id) {
        return findById(id);
    }
}
